.\" Copyright (c) 2008-2020 Julien Nadeau Carriere <vedge@csoft.net>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\" 
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
.\" (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 8, 2008
.Dt AG_EDITABLE 3
.Os
.ds vT Agar API Reference
.ds oS Agar 1.3
.Sh NAME
.Nm AG_Editable
.Nd agar text input widget
.Sh SYNOPSIS
.Bd -literal
#include <agar/core.h>
#include <agar/gui.h>
.Ed
.Sh DESCRIPTION
.\" IMAGE(http://libagar.org/widgets/AG_Editable.png, "The AG_Editable widget (in green)")
The
.Nm
widget implements low-level text edition.
.Nm
may be bound to a fixed-size buffer containing a "C" string (i.e., a
NUL-terminated string), or a dynamically-sized
.Xr AG_TextElement 3 .
.Pp
The string bound to
.Nm
may use different encodings (support for US-ASCII, UTF-8 and UCS-4 is built-in,
conversion to/from other encodings requires that Agar be built with
.Xr iconv 3
support).
.Pp
The
.Nm
widget is a "low-level" editor which implements an editable field (single
or multi-line), but with no decorations or scrolling ability.
The more commonly used
.Xr AG_Textbox 3
widget itself embeds an
.Nm
and also adds decorations, scrollbars and a text label.
.Pp
The
.Nm
API also includes methods for accessing the working buffer directly
(see
.Sx BUFFER ACCESS ROUTINES
section below).
This provides developers with a consistent interface for extending the
low-level functionality of the widget (for example, "Copy", "Paste", "Delete"
and "Select All" functions can be implemented externally in this way).
.Sh INHERITANCE HIERARCHY
.Xr AG_Object 3 ->
.Xr AG_Widget 3 ->
.Nm .
.Sh INITIALIZATION
.nr nS 1
.Ft "AG_Editable *"
.Fn AG_EditableNew "AG_Widget *parent" "Uint flags"
.Pp
.Ft "void"
.Fn AG_EditableBindUTF8 "AG_Editable *ed" "char *buffer" "AG_Size bufferSize"
.Pp
.Ft "void"
.Fn AG_EditableBindASCII "AG_Editable *ed" "char *buffer" "AG_Size bufferSize"
.Pp
.Ft "void"
.Fn AG_EditableBindEncoded "AG_Editable *ed" "const char *encoding" "char *buffer" "AG_Size bufferSize"
.Pp
.Ft "void"
.Fn AG_EditableBindText "AG_Editable *ed" "AG_TextElement *txt"
.Pp
.Ft void
.Fn AG_EditableSetLang "AG_Editable *ed" "enum ag_language lang"
.Pp
.Ft void
.Fn AG_EditableSetExcl "AG_Editable *ed" "int enable"
.Pp
.Ft void
.Fn AG_EditableSetPassword "AG_Editable *ed" "int enable"
.Pp
.Ft void
.Fn AG_EditableSetWordWrap "AG_Editable *ed" "int enable"
.Pp
.Ft void
.Fn AG_EditableSetIntOnly "AG_Editable *ed" "int enable"
.Pp
.Ft void
.Fn AG_EditableSetFltOnly "AG_Editable *ed" "int enable"
.Pp
.Ft void
.Fn AG_EditableSizeHint "AG_Editable *ed" "const char *text"
.Pp
.Ft void
.Fn AG_EditableSizeHintPixels "AG_Editable *ed" "Uint w" "Uint h"
.Pp
.Ft void
.Fn AG_EditableSizeHintLines "AG_Editable *ed" "Uint nLines"
.Pp
.Ft "void"
.Fn AG_EditableAutocomplete "AG_Editable *ed" "void (*fn)(AG_Event *)" "const char *fnArgs" "..."
.Pp
.Ft "void"
.Fn AG_EditableCloseAutocomplete "AG_Editable *ed"
.Pp
.nr nS 0
The
.Fn AG_EditableNew
function allocates, initializes, and attaches a new
.Nm
widget.
Acceptable
.Fa flags
include:
.Bl -tag -width "AG_EDITABLE_ABANDON_FOCUS "
.It AG_EDITABLE_MULTILINE
Causes newlines to be entered literally into the string, and arranges for
horizontal and vertical scrollbars to appear if the text is larger than the
display area.
.It AG_EDITABLE_WORDWRAP
Enable word wrapping in multiline mode.
.It AG_EDITABLE_MULTILINGUAL
Allow the user to select different languages from the right-click popup
menu (provided the widget is bound to an
.Xr AG_TextElement 3 ) .
.It AG_EDITABLE_EXCL
By default, external changes to the contents of the buffer are allowed and
handled in a safe manner (at the cost of frequent character set conversions
and periodical redrawing of the widget).
If
.Dv AG_EDITABLE_EXCL
is set,
.Nm
will assume exclusive access to the buffer, permitting some important
optimizations (i.e., periodic redrawing and character set conversions
are avoided).
.It AG_EDITABLE_UPPERCASE
Display all characters in upper-case.
.It AG_EDITABLE_LOWERCASE
Display all characters in lower-case.
.It AG_EDITABLE_PASSWORD
Password-style entry where characters are hidden.
Use
.Fn AG_EditableSetPassword
to change at runtime.
.It AG_EDITABLE_ABANDON_FOCUS
Arrange for the widget to abandon its focus when the return key is pressed.
.It AG_EDITABLE_INT_ONLY
Restricts input to integers only.
Use
.Fn AG_EditableSetIntOnly
to change at runtime.
.It AG_EDITABLE_FLT_ONLY
Restricts input to floating-point numbers in decimal and scientific
notation ("inf" and the Unicode symbol for Infinity may also be used).
Use
.Fn AG_EditableSetFltOnly
to change at runtime.
.It AG_EDITABLE_CATCH_TAB
Cause tabs to be entered literally into the string (by default, the tab
key moves focus to the next widget).
.It AG_EDITABLE_NOSCROLL
The view is normally scrolled automatically such that the cursor is always
visible.
This flag disables this behavior.
.It AG_EDITABLE_NOSCROLL_ONCE
Prevents automatic scrolling like
.Dv AG_EDITABLE_NOSCROLL ,
but only for the next rendering cycle.
.It AG_EDITABLE_NO_KILL_YANK
Disable Kill (ctrl-K) and Yank (ctrl-Y).
.It AG_EDITABLE_NO_ALT_LATIN1
Disable alt-key mappings to extended Latin-1 characters.
.It AG_EDITABLE_NOPOPUP
Disable the standard right-click popup menu.
.It AG_EDITABLE_READONLY
Make the string read-only.
This has the same effect as using
.Xr AG_WidgetDisable 3 ,
except that the textbox is not grayed out.
.It AG_EDITABLE_HFILL
Expand horizontally in parent container.
.It AG_EDITABLE_VFILL
Expand vertically in parent container.
.It AG_EDITABLE_EXPAND
Shorthand for
.Dv AG_EDITABLE_HFILL | AG_EDITABLE_VFILL .
.El
.Pp
The
.Fn AG_EditableBindUTF8
and
.Fn AG_EditableBindASCII
functions bind the
.Nm
to a fixed-size buffer containing a C string in UTF-8 or
US-ASCII encoding, respectively.
The
.Fa bufferSize
argument indicates the complete size of the buffer in bytes.
.Pp
.Fn AG_EditableBindEncoded
binds to a fixed-size buffer containing a C string in the specified
encoding.
Support for the "US-ASCII" and "UTF-8" encodings is built-in, but
conversion to other encodings requires that Agar be compiled with
.Xr iconv 3
support (see
.Xr iconv_open 3
for the complete list of supported encodings).
.Pp
.Fn AG_EditableBindText
connects the
.Nm
to an
.Xr AG_TextElement 3 .
.Pp
The
.Fn AG_EditableSetLang
function selects the specified language for the current
.Xr AG_TextElement 3 .
.Pp
The
.Fn AG_EditableSetExcl
function sets exclusive access to the buffer.
Enable only if the bound string is guaranteed not to change externally (see
.Dv AG_EDITABLE_EXCL
flag description above).
.Pp
The
.Fn AG_EditableSetPassword
function enables or disables password-type input, where characters are
substituted for
.Sq *
in the display.
.Pp
.Fn AG_EditableSetWordWrap
enables/disable word wrapping.
.Pp
.Fn AG_EditableSetIntOnly
restricts input to integers (see flags)
.Fn AG_EditableSetFltOnly
restricts input to real numbers (see flags).
.Pp
.Fn AG_EditableSizeHint
requests that the initial geometry of
.Fa ed
is to be sufficient to display the string
.Fa text
in its entirety.
The
.Fn AG_EditableSizeHintPixels
variant accepts arguments in pixels.
.Fn AG_EditableSizeHintLines
accepts a line count.
.Pp
.Fn AG_EditableAutocomplete
sets up an autocomplete routine
.Fa fn ,
which will be passed a pointer to an
.Xr AG_Tlist 3
as first argument.
This routine is expected to populate the tlist with suggestions based on the
current buffer contents.
If the
.Fa fn
argument is NULL, disable autocomplete (closing any active windows).
If an autocomplete context has already been configured, only its function
and arguments are updated (and any active timers are cancelled).
If non-NULL,
.Fa fnArgs
indicates additional
.Xr AG_Event 3
style arguments to be passed to the autocomplete routine.
.Pp
.Fn AG_EditableCloseAutocomplete
closes any active autocomplete windows.
If there are no autocomplete windows open or an autocomplete context has
not been defined then this routine is a no-op.
.Sh STRING UTILITY ROUTINES
.nr nS 1
.Ft void
.Fn AG_EditablePrintf "AG_Editable *ed" "const char *fmt" "..."
.Pp
.Ft void
.Fn AG_EditableSetString "AG_Editable *ed" "const char *s"
.Pp
.Ft void
.Fn AG_EditableCatString "AG_Editable *ed" "const char *fmt" "..."
.Pp
.Ft void
.Fn AG_EditableCatStringS "AG_Editable *ed" "const char *s"
.Pp
.Ft void
.Fn AG_EditableClearString "AG_Editable *ed"
.Pp
.Ft "char *"
.Fn AG_EditableDupString "AG_Editable *ed"
.Pp
.Ft "AG_Size"
.Fn AG_EditableCopyString "AG_Editable *ed" "char *dst" "AG_Size dst_size"
.Pp
.Ft int
.Fn AG_EditableInt "AG_Editable *ed"
.Pp
.Ft float
.Fn AG_EditableFlt "AG_Editable *ed"
.Pp
.Ft double
.Fn AG_EditableDbl "AG_Editable *ed"
.Pp
.nr nS 0
The
.Fn AG_EditablePrintf
function uses
.Xr vsnprintf 3
to overwrite the contents of the buffer.
If the
.Fa fmt
argument is NULL, a NUL string is assigned instead.
.Pp
.Fn AG_EditableSetString
overwrites the contents of the buffer with the given string.
The argument may be NULL to clear the string.
.Pp
.Fn AG_EditableCatString
appends the given string at the end of the buffer contents.
Return 0 on success or -1 if buffer is too small or truncation occurred.
.Pp
.Fn AG_EditableClearString
clears the contents of the buffer.
.Pp
The
.Fn AG_EditableDupString
function returns a copy of the text buffer, as-is.
If insufficient memory is available, NULL is returned.
.Fn AG_EditableCopyString
copies the contents of the text buffer to a fixed-size buffer
(up to
.Fa dst_size
- 1 bytes will be copied).
Returns the number of bytes that would have been copied were
.Fa dst_size
unlimited (i.e., if the return value is >=
.Fa dst_size ,
truncation has occurred).
Both
.Fn AG_EditableDupString
and
.Fn AG_EditableCopyString
return the raw contents of the text buffer, without performing
any character set conversion.
.Pp
.Fn AG_EditableInt ,
.Fn AG_EditableFlt
and
.Fn AG_EditableDbl
perform conversion of the string contents to
.Ft int
.Ft float
and
.Ft double ,
respectively and return the value.
Note that the
.Xr AG_Numerical 3
widget is usually a better option than
.Nm
for editing numbers.
.\" MANLINK(AG_EditableBuffer)
.Sh BUFFER ACCESS ROUTINES
.nr nS 1
.Ft "AG_EditableBuffer *"
.Fn AG_EditableGetBuffer "AG_Editable *ed"
.Pp
.Ft "void"
.Fn AG_EditableReleaseBuffer "AG_Editable *ed" "AG_EditableBuffer *buf"
.Pp
.Ft "void"
.Fn AG_EditableClearBuffer "AG_Editable *ed" "AG_EditableBuffer *buf"
.Pp
.Ft "int"
.Fn AG_EditableGrowBuffer "AG_Editable *ed" "AG_EditableBuffer *buf" "AG_Char *ins" "AG_Size nIns"
.Pp
.Ft "int"
.Fn AG_EditableCut "AG_Editable *ed" "AG_EditableBuffer *buf" "AG_EditableClipboard *cb"
.Pp
.Ft "void"
.Fn AG_EditableCopyChunk "AG_Editable *ed" "AG_EditableClipboard *cb" "AG_Char *s" "AG_Size len"
.Pp
.Ft "int"
.Fn AG_EditableCopy "AG_Editable *ed" "AG_EditableBuffer *buf" "AG_EditableClipboard *cb"
.Pp
.Ft "int"
.Fn AG_EditablePaste "AG_Editable *ed" "AG_EditableBuffer *buf" "AG_EditableClipboard *cb"
.Pp
.Ft "int"
.Fn AG_EditableDelete "AG_Editable *ed" "AG_EditableBuffer *buf"
.Pp
.Ft "void"
.Fn AG_EditableSelectAll "AG_Editable *ed" "AG_EditableBuffer *buf"
.Pp
.nr nS 0
The
.Fn AG_EditableGetBuffer
function returns a locked handle to the internal, working buffer associated
with an
.Nm
widget.
The buffer structure is defined as follows:
.Bd -literal
typedef struct ag_editable_buffer {
	AG_Variable *var;            /* Variable binding (if any) */
	AG_Char *s;                  /* Buffer contents */
	AG_Size len;                 /* Length of string (chars) */
	AG_Size maxLen;              /* Available buffer size (bytes) */
	int reallocable;             /* Buffer can be realloc'd */
} AG_EditableBuffer;
.Ed
.Pp
The contents of
.Va s
may be modified directly (any change to the effective string length must
be reflected in the
.Va len
field).
.Pp
The
.Fn AG_EditableReleaseBuffer
function unlocks and releases working buffer.
It must be called following the
.Fn AG_EditableGetBuffer
call, once the caller has finished accessing the buffer.
.Pp
.Fn AG_EditableClearBuffer
frees the contents of the buffer, reinitializing to an empty string.
.Pp
The
.Fn AG_EditableGrowBuffer
function attempts to increase the size of the buffer in order to accomodate
the
.Fa nIns
characters in the
.Fa ins
argument.
If insufficient space is available (e.g., this is a fixed-size buffer or we
ran out of memory), the function fails and returns -1.
.Pp
.Fn AG_EditableCopyChunk
copies the specified string of characters to the clipboard.
.Fn AG_EditableCopy
copies the whole selection to the clipboard (the
.Fn AG_EditableCut
variant subsequently deletes the selection).
.Fn AG_EditablePaste
pastes the contents of the clipboard to the current cursor position.
.Fn AG_EditableDelete
deletes the current selection, if any.
The return value of those functions is 1 if the buffer has been modified,
or 0 if the buffer is unchanged.
.Pp
.Fn AG_EditableSelectAll
selects all characters in the buffer.
.Sh CURSOR CONTROL ROUTINES
.nr nS 1
.Ft int
.Fn AG_EditableMapPosition "AG_Editable *ed" "AG_EditableBuffer *buf" "int x" "int y" "int *pos"
.Pp
.Ft int
.Fn AG_EditableMoveCursor "AG_Editable *ed" "AG_EditableBuffer *buf" "int x" "int y"
.Pp
.Ft int
.Fn AG_EditableGetCursorPos "AG_Editable *ed"
.Pp
.Ft int
.Fn AG_EditableSetCursorPos "AG_Editable *ed" "AG_EditableBuffer *buf" "int pos"
.Pp
.nr nS 0
The
.Fn AG_EditableMapPosition
function translates pixel coordinates
.Fa x
and
.Fa y
to a character position within the text buffer.
On success, the position is returned into
.Fa pos .
The function returns 0 on success or -1 on failure.
.Pp
.Fn AG_EditableMoveCursor
moves the text cursor to the position closest to the pixel coordinates
.Fa mx
and
.Fa my .
.Pp
.Fn AG_EditableGetCursorPos
returns the current position of the cursor in the text.
The return value is only valid as long as the widget remains locked.
The position can also be retrieved from the
.Va pos
variable (see
.Sx STRUCTURE DATA ) .
.Pp
.Fn AG_EditableSetCursorPos
tries to move the cursor to the specified position in the string (bounds
checking is performed).
If the
.Fa pos
argument is -1, the cursor is moved to the end of the string.
The new position of the cursor is returned.
.Sh BINDINGS
The
.Nm
widget provides the following bindings:
.Pp
.Bl -tag -compact -width "AG_TextElement *text "
.It Va char *string
Bound fixed-size buffer containing a "C" string (i.e., a NUL-terminated string)
in the specified encoding (UTF-8 by default).
.It Va AG_TextElement *text
Bound
.Xr AG_TextElement 3 .
.It Va char *placeholder
An optional string of text to display whenever the text buffer is empty.
.El
.Sh EVENTS
The
.Nm
widget generates the following events:
.Bl -tag -width 2n
.It Fn editable-return "void"
Return was pressed and
.Dv AG_EDITABLE_MULTILINE
is not set.
.It Fn editable-prechg "void"
The string is about to be modified.
.It Fn editable-postchg "void"
The string was just modified.
.El
.Sh STRUCTURE DATA
For the
.Ft AG_Editable
object:
.Pp
.Bl -tag -compact -width "enum ag_language lang "
.It Ft int pos
Current cursor position (ranging from 0 to the current buffer's
.Va len
value).
.It Ft int sel
Current selection, expressed as an offset from the cursor
(0 = there is no selection).
.It Ft AG_Text *text
An initially empty
.Xr AG_TextElement 3
used as the default binding (where
.Fn AG_EditableBind*
is not used).
.It Ft char *encoding
Character set for the bound string.
This may be set to "US-ASCII" or "UTF-8" (the default).
Other character sets are supported if Agar was compiled with
.Xr iconv 3
support.
.It Ft enum ag_language lang
Currently selected language (for
.Xr AG_TextElement 3
bindings).
Read-only; use
.Fn AG_EditableSetLang
to change.
.El
.Sh EXAMPLES
The following code fragment binds a
.Nm
to a string contained in a fixed-size buffer:
.Bd -literal -offset indent
char name[32];
AG_Editable *ed;

ed = AG_EditableNew(parent, 0);
AG_EditableBindUTF8(ed, name, sizeof(name));
.Ed
.Pp
See
.Xr AG_Textbox 3
for an example autocomplete routine (note that the
.Fn AG_TextboxAutocomplete
call is an alias for
.Fn AG_EditableAutocomplete ) .
.Sh SEE ALSO
.Xr AG_Intro 3 ,
.Xr AG_Text 3 ,
.Xr AG_Textbox 3 ,
.Xr AG_TextElement 3 ,
.Xr AG_Tlist 3 ,
.Xr AG_Widget 3 ,
.Xr AG_Window 3
.Sh HISTORY
An
.Ft AG_Textbox
first appeared in Agar 1.0.
It was rewritten as a front-end to
.Xr AG_Editable 3
in Agar 1.3.2.
The clipboard and direct buffer access routines were added in Agar 1.4.2.
.Dv AG_EDITABLE_UPPERCASE
and
.Dv AG_EDITABLE_LOWERCASE
appeared in Agar 1.6.0.
The former
.Dv AG_EDITABLE_NOEMACS
flag was renamed
.Dv AG_EDITABLE_NO_KILL_YANK
and
.Dv AG_EDITABLE_NOLATIN1
was renamed
.Dv AG_EDITABLE_NO_ALT_LATIN1
in Agar 1.6.0.
Clipboard integration,
.Fn AG_EditableAutocomplete
and
.Fn AG_EditableCatString
appeared in Agar 1.6.0.
